package org.ccay.web.support.servlet;

import java.io.IOException;

import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;

import org.ccay.core.cache.ICacheManagement;
import org.ccay.core.cache.ICacheNotifyHandler;
import org.ccay.core.cache.ehcache.CacheEvent;
import org.ccay.core.dispatcher.EventUtil;


/**
 * 缓存同步服务
 */
@Named("/servlet/cache")
public class CacheSyncServlet extends HttpServlet  { 
	private static final long serialVersionUID = 5037547880439900799L;
	/**
	 * 缓存管理器，可能为ehCache或者iCache
	 */
	@Inject
	private ICacheManagement cacheManager ;
	/* (non-Javadoc)
	 * @see www.ccay.org.ccay.web.support.servlet.AbstractInternalServlet#doService(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
		int cacheType = Integer.valueOf(request.getParameter("type"));
		String key =  request.getParameter("key");
		String cacheName =  request.getParameter("name");
		//是否分布式缓存，分布式缓存时集群中其他服务器不响应更新指令，但是仍然要响应Notify（通知）
		boolean distributed ="true".equals(request.getParameter("distributed"));	 

		if (!distributed){
			evictThisServer(cacheType, key, cacheName);
		} 
		
		dispathNotify(cacheType, cacheName, distributed);
	}

	/** 
	 * 擦除当前Server
	 * @param cacheType
	 * @param key
	 * @param cacheName
	 */
	private void evictThisServer(int cacheType, String key, String cacheName) {
		if(CacheEvent.EVICT_ALL_NAME == cacheType) {
			cacheManager.clearAll();
		}else if (CacheEvent.EVICT_ALL == cacheType) {
			// 擦除某Name
			cacheManager.clearName(cacheName);
		} else if (CacheEvent.EVICT_ONE == cacheType) {
			// 擦除一个KEY
			cacheManager.remove(cacheName, key);
		}
	}
	
	/** 
	 * 分发通知事件
	 * @param cacheType
	 * @param cacheName
	 * @param distributed
	 */
	private void dispathNotify(int cacheType, String cacheName, boolean distributed) {
		CacheEvent e = new CacheEvent(cacheType);
		e.setCacheName(cacheName);
		e.setDistributed(distributed);
		
		EventUtil.dispatch(ICacheNotifyHandler.class, null, e);
	}
}
